package com.ruoyi.messages.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.ruoyi.SpringWebSocket.MyWsHandler;
import com.ruoyi.agent.domain.SysAgent;
import com.ruoyi.agent.mapper.SysAgentMapper;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.messages.domain.SysBalanceWarning;
import com.ruoyi.messages.domain.VO.SysNotifyVO;
import com.ruoyi.messages.mapper.SysBalanceWarningMapper;
import com.ruoyi.orderParent.domain.SysOrder;
import com.ruoyi.orderParent.domain.SysOrderParent;
import com.ruoyi.report.domain.SysReportDetails;
import com.ruoyi.store.domain.SysStore;
import com.ruoyi.store.mapper.SysStoreMapper;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import net.sf.jsqlparser.expression.LongValue;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.ruoyi.messages.mapper.SysNotifyMapper;
import com.ruoyi.messages.domain.SysNotify;
import com.ruoyi.messages.service.ISysNotifyService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import static com.ruoyi.common.utils.PageUtils.startPage;

/**
 * 消息通知Service业务层处理
 *
 * @author ruoyi
 * @date 2024-06-26
 */
@Service
public class SysNotifyServiceImpl implements ISysNotifyService
{
    @Autowired
    private SysNotifyMapper sysNotifyMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysStoreMapper sysStoreMapper;

    @Autowired
    private SysAgentMapper agentMapper;

    @Autowired
    private SysBalanceWarningMapper balanceWarningMapper;

    @Autowired
    private MyWsHandler myWsHandler;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysDeptMapper deptMapper;

    /**
     * 查询消息通知
     *
     * @param id 消息通知主键
     * @return 消息通知
     */
    @Override
    public SysNotify selectSysNotifyById(Long id)
    {
        return sysNotifyMapper.selectSysNotifyById(id);
    }

    /**
     * 查询消息通知列表
     *
     * @param sysNotify 消息通知
     * @return 消息通知
     */
    @Override
    public List<SysNotifyVO> selectSysNotifyList(SysNotify sysNotify)
    {

        List<SysNotify> sysNotifies = new ArrayList<>();
        //通过deptid判断当前用户是什么地位
        Long deptId = SecurityUtils.getDeptId();
        //通过查询dept表对应的type得知该用户的地位
        SysDept sysDept = deptMapper.selectDeptById(deptId);
        String type = sysDept.getType();
        String key ="";
        if (type=="0"||type.equals("0")) {
            key="notify_agent_0";
            //说明是管理端用户
            //管理商端可以看到自己商铺下余额不足提醒。商家下单背调，批量订单
            //todo 应该还有代理商余额不足提醒
            //首先查询管理端下的所有商铺的deptIds
            Long agentId = 0l;
           List<SysStore> sysStores= sysStoreMapper.selectSysStoreByAgentId(agentId);
            Set<Long> storeDeptIds = sysStores.stream().map(SysStore::getDeptId).collect(Collectors.toSet());

            List<Long> storeDeptIdsList = new ArrayList<>(storeDeptIds);

            startPage();
           sysNotifies= sysNotifyMapper.selectSysNotifyListByManage(storeDeptIdsList);

        }
       else if (type=="1"||type.equals("1")) {

            //说明是代理商用户
            //根据当前用户部门id查询对应的代理商
            List<SysAgent> agents = agentMapper.selectSysAgentByDeptId(deptId);
            if (CollectionUtils.isEmpty(agents)) {
                throw new ServiceException("当前代理商用户异常");
            }
            Long agentId =agents.get(0).getId();
            key="notify_agent_"+agentId;
            List<SysStore> sysStores= sysStoreMapper.selectSysStoreByAgentId(agentId);
            Set<Long> storeDeptIds = sysStores.stream().map(SysStore::getDeptId).collect(Collectors.toSet());

            List<Long> storeDeptIdsList = new ArrayList<>(storeDeptIds);
            storeDeptIdsList.add(deptId);
            startPage();
            sysNotifies= sysNotifyMapper.selectSysNotifyListByManage(storeDeptIdsList);

        }
        else if (type=="2"||type.equals("2")) {
            //说明是商铺用户
            List<SysStore> sysStores = sysStoreMapper.selectSysStoreByDeptId(deptId);
            if (CollectionUtils.isEmpty(sysStores)) {
                throw new ServiceException("商户信息有误");
            }
            key="notify_store_"+sysStores.get(0).getId();
            //商铺可以看到自己的余额不足提醒，下单 批量下单  候选人授权和报告已出信息
            sysNotifies= sysNotifyMapper.selectSysNotifyListByDeptId(deptId);

        }
        else if (type!="0"&&type!="1"&&type!="2"){
            throw new ServiceException("当前用户登录信息异常");
        }

        //对sysNotifies进行封装
        List<SysNotifyVO> sysNotifyVOS = new ArrayList<>();
        //查询对应的未读信息id为集合
        Set<String> keys = redisTemplate.opsForHash().keys(key);

        for (SysNotify notify : sysNotifies) {
            SysNotifyVO sysNotifyVO = new SysNotifyVO();
            BeanUtils.copyProperties(notify,sysNotifyVO);
            sysNotifyVO.setRead(true);
            if (keys.contains(notify.getId().toString())) {
                sysNotifyVO.setRead(false);
            }
            sysNotifyVOS.add(sysNotifyVO);
        }

        //todo 代理商余额不足提醒

        return sysNotifyVOS;
    }

    /**
     * 新增消息通知
     *
     * @param sysNotify 消息通知
     * @return 结果
     */
    @Override
    @Transactional
    public int insertSysNotify(SysNotify sysNotify)
    {
        sysNotify.setType("0");
        sysNotify.setCreateTime(DateUtils.getNowDate());
        int i = sysNotifyMapper.insertSysNotify(sysNotify);
        sysNotify.setUserId(SecurityUtils.getUserId());
        sysNotify.setDeptId(SecurityUtils.getDeptId());
        new MyWsHandler(userMapper,sysStoreMapper,agentMapper).sendNotify(sysNotify);
        //进行消息通知
        return i;
    }

    /**
     * 修改消息通知
     *
     * @param sysNotify 消息通知
     * @return 结果
     */
    @Override
    public int updateSysNotify(SysNotify sysNotify)
    {
        sysNotify.setUpdateTime(DateUtils.getNowDate());
        return sysNotifyMapper.updateSysNotify(sysNotify);
    }

    /**
     * 批量删除消息通知
     *
     * @param ids 需要删除的消息通知主键
     * @return 结果
     */
    @Override
    public int deleteSysNotifyByIds(Long[] ids)
    {
        return sysNotifyMapper.deleteSysNotifyByIds(ids);
    }

    /**
     * 删除消息通知信息
     *
     * @param id 消息通知主键
     * @return 结果
     */
    @Override
    public int deleteSysNotifyById(Long id)
    {
        return sysNotifyMapper.deleteSysNotifyById(id);
    }


//    //检查当前的店铺是否余额不足
//    @Async("AsyncPool")
//    @Transactional
//    public void CheckStorePrice(Long deptId) {
//
//        //通过deptId查询到对应商铺对象的余额值
//        List<SysStore> sysStores = sysStoreMapper.selectSysStoreByDeptId(deptId);
//        if (!CollectionUtils.isEmpty(sysStores)) {
//
//            SysStore sysStore = sysStores.get(0);
//            BigDecimal storeBalance = sysStore.getBalance();
//            //通过店铺id查询到对应的代理商，通过代理商deptid查询余额预警表的预警值，进行比对
//
//            Long agentId = sysStore.getAgentId();
//            Long agentDeptId;
//            if (agentId!=0) {
//                //说明是代理商下的店铺
//                SysAgent sysAgent = agentMapper.selectSysAgentById(agentId);
//               agentDeptId = sysAgent.getDeptId();
//            }else {
//                //就是管理商下的店铺
//                agentDeptId = 100l;
//            }
//
//           List<SysBalanceWarning> balanceWarnings= balanceWarningMapper.selectSysBalanceWarningByDeptId(agentDeptId);
//
//           //todo 当创建代理商时默认插入预警值 默认100
//           if (CollectionUtils.isEmpty(balanceWarnings)) {
//               throw new ServiceException("代理商未设置预警余额值");
//           }
//            BigDecimal warningValue = balanceWarnings.get(0).getWarningValue();
//            //如果不足则新增一条消息并发送消息给对应的用户和代理商
//            if (storeBalance.compareTo(warningValue)!=1) {
//                //说明余额小于等于预警值，应该发送了
//
//                //创建一条消息：
//                SysNotify sysNotify = new SysNotify().setType("0").setName("商铺: " + sysStore.getName() + "剩余余额：" + storeBalance + ",不足于：" + warningValue + ",请尽快充值")
//                        .setDataId(sysStore.getId()).setUserId(sysStore.getUserId()).setDeptId(sysStore.getDeptId());
//                //插入数据库中
//                //发送信息给对应用
//                sysNotify.setCreateTime(DateUtils.getNowDate());
//                sysNotifyMapper.insertSysNotify(sysNotify);
//
//                //向redis中设置(以代理商和商铺为单位)未读状态 (key:store_storeid : 消息id ，是否已读)
//
//                Long storeId = sysStore.getId();
//                String storeKey = "notify_store_"+storeId;
//                String agentKye = "notify_agent_"+agentId;
//                HashOperations hashOperations = redisTemplate.opsForHash();
//                //0表示未读，当已读后会删除该小key
//                hashOperations.put(storeKey,sysNotify.getId().toString(),"0");   //商铺未读
//                hashOperations.put(agentKye,sysNotify.getId().toString(),"0");   //代理商未读
//
//
//
//                myWsHandler.sendNotify(sysNotify);
//
//
//            }
//
//
//
//        }
//
//    }
//
//    //当单个订单被下单
//    @Async("AsyncPool")
//    public void MakeOrder(SysOrder order){
//
//        //产生一条消息
//        SysNotify sysNotify = new SysNotify().setDeptId(order.getDeptId()).setUserId(order.getUserId()).setName("商家:" + order.getStoreName() + " ,消费：" + order.getAmount() + "元，背调订单编号：" + order.getNumber()).setType("1").setDataId(order.getId());
//        sysNotify.setCreateTime(DateUtils.getNowDate());
//        sysNotifyMapper.insertSysNotify(sysNotify);
//
//        //向redis中插入未读信息：
//        String storeKey = "notify_store_"+order.getStoreId();
//        String agentKye = "notify_agent_"+order.getAgentId();
//        HashOperations hashOperations = redisTemplate.opsForHash();
//        //0表示未读，当已读后会删除该小key
//        hashOperations.put(storeKey,sysNotify.getId().toString(),0);   //商铺未读
//        hashOperations.put(agentKye,sysNotify.getId().toString(),0);   //代理商未读
//
//        //发送信息给对应用
//
//        myWsHandler.sendNotify(sysNotify);
//
//
//
//    }
//
//    //当批量订单被下单
//    @Async("AsyncPool")
//    public void MakeOrders(SysOrderParent orderParent){
//
//        //产生一条消息
//        SysNotify sysNotify = new SysNotify().setDeptId(orderParent.getDeptId()).setUserId(orderParent.getUserId()).setName("商家:" + orderParent.getStoreName() + " ,消费：" + orderParent.getAmount() + "元，批量订单批次号：" + orderParent.getNumber()).setType("2").setDataId(orderParent.getId());
//        sysNotify.setCreateTime(DateUtils.getNowDate());
//        sysNotifyMapper.insertSysNotify(sysNotify);
//
//        //向redis中插入未读信息：
//        String storeKey = "notify_store_"+orderParent.getStoreId();
//        String agentKye = "notify_agent_"+orderParent.getAgentId();
//        HashOperations hashOperations = redisTemplate.opsForHash();
//        //0表示未读，当已读后会删除该小key
//        hashOperations.put(storeKey,sysNotify.getId().toString(),0);   //商铺未读
//        hashOperations.put(agentKye,sysNotify.getId().toString(),0);   //代理商未读
//
//        //发送信息给对应用
//
//        myWsHandler.sendNotify(sysNotify);
//
//
//
//    }
//
//    //候选人授权通知
//    @Async("AsyncPool")
//    public void UserAuthorized(SysOrder order) {
//
//        //产生一条消息
//        SysNotify sysNotify = new SysNotify().setDeptId(order.getDeptId()).setUserId(order.getUserId()).setName(order.getNumber()+" 候选人："+order.getCdName()+" 已授权").setDataId(order.getId()).setType("3");
//        sysNotify.setCreateTime(DateUtils.getNowDate());
//        sysNotifyMapper.insertSysNotify(sysNotify);
//
//        //向redis中插入未读信息：
//        String storeKey = "notify_store_"+order.getStoreId();
////        String agentKye = "notify_agent_"+order.getAgentId();
//        HashOperations hashOperations = redisTemplate.opsForHash();
//        //0表示未读，当已读后会删除该小key
//        hashOperations.put(storeKey,sysNotify.getId().toString(),0);   //商铺未读
////        hashOperations.put(agentKye,sysNotify.getId(),0);   //代理商未读
//
//        //发送信息给对应用
//
//        myWsHandler.sendNotify(sysNotify);
//
//
//
//    }
//
//    //线上报告已出
//    @Async("AsyncPool")
//    public void reportMaked(SysOrder order) {
//
//        //产生一条消息
//        SysNotify sysNotify = new SysNotify().setDeptId(order.getDeptId()).setUserId(order.getUserId()).setName(order.getNumber()+" 候选人："+order.getCdName()+" 已授权");
//        sysNotify.setCreateTime(DateUtils.getNowDate());
//        sysNotifyMapper.insertSysNotify(sysNotify);
//
//        //向redis中插入未读信息：
//        String storeKey = "notify_store_"+order.getStoreId();
////        String agentKye = "notify_agent_"+order.getAgentId();
//        HashOperations hashOperations = redisTemplate.opsForHash();
//        //0表示未读，当已读后会删除该小key
//        hashOperations.put(storeKey,sysNotify.getId().toString(),0);   //商铺未读
////        hashOperations.put(agentKye,sysNotify.getId(),0);   //代理商未读
//
//        //发送信息给对应用
//
//        myWsHandler.sendNotify(sysNotify);
//
//
//
//    }
}
